Repository navigation
Conversation
ad9482f to
aeb677f
Compare
…he line When an encoded word does not fit in the remaining space of a line, _fold_as_ew shrinks the chunk being encoded one character at a time until it fits. Nothing stops it from shrinking the chunk to nothing, and an empty chunk makes no progress: the loop appends an empty encoded word and a new continuation line forever. This is reachable whenever a single character's encoded form is wider than a fresh continuation line, e.g. any character outside the BMP with max_line_length=20 (the q-encoded word is 24 characters). The two earlier fixes in this area (bpo-33529, bpo-36564) handled lines too short for the RFC 2047 chrome, but not lines too short for the chrome plus one character. This keeps at least one character in the chunk, so the loop always advances and the line runs over max_line_length instead. That matches what _refold_parse_tree already does when it cannot fold a part at all, and avoids raising for widths that work for every other input. The regression test pins the exact output, as the earlier two did. The Hypothesis property checks that folding any unstructured value at any width either raises HeaderParseError (only possible at widths of 13 or fewer, where no encoded word fits) or reparses to the same value modulo leading whitespace, which the parser drops.
7f30bad to
61e55a2
Compare
|
Thanks for finding this. I actually thought I had observed that case during those previous changes, but I must be mis-remembering. Either that, or there's an open issue I can't find ;) I'll have to look in to the hypothesis stuff...looking at it without understanding hypothesis it is completely opaque to me what exactly it is testing. As for the encoded word bug, please separate that out into a new issue. If/how to fix it should be a separate discussion. I prefer not to add "expected failure" tests. |
…ok-alikes The round trip property cannot cover text that is itself a well-formed encoded word, because such text is written out unencoded and decodes to something else on reparse. That is now tracked separately as pythongh-160148, so point at it from the strategy rather than carrying an expected failure here.
61e55a2 to
1cb3b3b
Compare
|
Done: the expected failure is removed from this PR and filed separately as #160148, with the test included in the issue text for reference. The branch now has only the infinite loop fix, its regression test, and the round-trip property (plus a comment pointing at #160148 for why the strategy avoids encoded-word look-alikes). On the Hypothesis test: it generates subjects from a small set of pieces (words, whitespace runs, RFC 5322 specials, 2/3/4-byte characters, |
Stacked on #159770; only the top two commits are new here.
When an encoded word does not fit in the remaining space of a line,
_fold_as_ewshrinks the chunk being encoded one character at a time until it fits. Nothing stops it from shrinking the chunk to nothing, and an empty chunk makes no progress: the loop appends an empty encoded word and a new continuation line forever.This is reachable whenever a single character's encoded form is wider than a fresh continuation line, e.g. any character outside the BMP at
max_line_length=20(the q-encoded word is 24 characters). The two earlier fixes in this area (bpo-33529, bpo-36564) handled lines too short for the RFC 2047 chrome, but not lines too short for the chrome plus one character.The fix keeps at least one character in the chunk, so the loop always advances and the line runs over
max_line_lengthinstead. That matches what_refold_parse_treealready does when it cannot fold a part at all, and avoids raising for widths that work for every other input.Tests, next to the two earlier infinite-loop regressions in
test_policy.py:None) either raisesHeaderParseError(only possible at widths of 13 or fewer, where no encoded word fits) or reparses to the same value modulo leading whitespace, which the parser drops. 100 examples take about 0.2 s; the explicit examples replay under the stubs.